%     AERO LOAD - программа для нагружения агрегатов самолета распределенной нагрузкой
%     Copyright (C) 2018-2024  Михаил Козлов
%     Сайт проекта: <http://www.fastenerdoctor.ru/>
%     Адрес электронной почты для связи с разработчиком:
%     <doctor.fastener@gmail.com>
% 
%     Эта программа является свободным программным обеспечением: Вы можете
%     распространять ее и/или изменять, соблюдая условия Универсальной общественной
%     лицензии GNU, опубликованной Фондом свободного программного обеспечения,
%     либо редакции 3, либо (на Ваше усмотрение) любой редакции, выпущенной позже.
% 
%     Эта программа распространяется в надежде на то, что она окажется полезной,
%     но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая даже подразумеваемую гарантию ТОВАРНОЙ ПРИГОДНОСТИ,
%     либо ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Ознакомьтесь с Универсальной общественной
%     лицензией GNU для получения более подробной информации.
% 
%     Вы должны были получить копию Универсальной общественной лицензии GNU
%     вместе с этой программой. Если Вы ее не получили, то перейдите по адресу:
%     <http://www.gnu.org/licenses/>.
% 
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
% 
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%     GNU General Public License for more details.
% 
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <https://www.gnu.org/licenses/>.

clc;
more off;

% #######################################################################################################
% ##                                                                                                   ##
% ##                                        НАСТРОЙКИ ПРОГРАММЫ                                        ##
% ##                                                                                                   ##
% #######################################################################################################

% Для включения возможности вывода информации на русском языке при выполнении программы в среде GNU Octave
% необходимо добавить в файл C:\Octave\Octave-4.4.0\share\octave\site\m\startup\octaverc  следующую строку:
% system("chcp 1251",1);

% ---------------------------------------- Параметры базы Patran ----------------------------------------

Model_length_unit              = 'mm'; % mm | m | inch | ft    % Используемая в модели единица измерения длины (данный параметр необходим для корректного расчета допусков в моделях, в которых единица измерения длины отлична от мм).

% --------------------------------------- Параметры ввода-вывода ----------------------------------------

Work_Directory                 = 'M:\Patran_work';          % Рабочая папка
Need_Reading_BDF_File          = 'TRUE'; % TRUE | FALSE     % TRUE - выполнить новое чтение bdf файла при запуске программы; FALSE - использовать базу, содержащуюся в памяти программы с предыдущего запуска.
Input_BDF_name                 = 'example';                 % Имя bdf файла c участком сетки для нагружения

Output_File_Format             = 'CSV'; % SES | CSV | BOTH | OFF    % Формат выходного файла (SES, CSV, BOTH - оба сразу), либо отключение (OFF) сохранения поля нагрузок в файл (полезно при выполнении итераций корректировки нагрузки).
Write_Current_Config           = 'TRUE'; % TRUE | FALSE             % Создание конфигурационного файла с текущими настройками нагружения

Load_Visualization             = 'TRUE'; % TRUE | FALSE     % Визуализация нагружения в графическом окне (только для MATLAB)
Window_Language                = 'RU'; % RU | EN            % Язык графического окна

% ------------------------------------ Источник настроек нагружения -------------------------------------

Settings_Source                = 'PROGRAM_TEXT'; % PROGRAM_TEXT | CONFIG_FILE    % PROGRAM_TEXT - настройки нагружения задаются ниже в тексте программы; CONFIG_FILE - настройки нагружения считываются из конфигурационного файла. При этом все настройки ниже по тексту программы игнорируются.
Config_File_Directory          = 'M:\Patran_work';                               % Папка с конфигурационным файлом
Config_File_Name               = 'Aero_Load_14-Jul-2019_02-32-11';                                       % Имя конфигурационного файла

% -------------------------------------------------------------------------------------------------------

%                                      ##############################
%                                      ##   НАСТРОЙКИ НАГРУЖЕНИЯ   ##
%                                      ##############################


% ====================================== ЗАДАНИЕ БАЗОВОЙ ПЛОСКОСТИ ======================================

% Базовая плоскость - это та плоскость, по нормали к которой должна действовать нагрузка Pn

% Способ задания базовой плоскости
Basic_Plane_Definition = 'THREE_POINTS'; % POINT_NORMAL | THREE_POINTS

                                         % POINT_NORMAL - плоскость задается по точке Z0 и нормали Z0 -> Z1
                                         % THREE_POINTS - плоскость задается по трем точкам D1, D2, D3; нормаль определяется последовательностью обхода D1 -> D2 -> D3

% Если Basic_Plane_Definition = POINT_NORMAL
    Z0 = [207 -32 161];
    Z1 = [204.676 -111.973 204.359];

% Если Basic_Plane_Definition = THREE_POINTS
    D1 = [0 0 0];
    D2 = [0 -400 0];
    D3 = [2000 0 0];


% ================================ ЗАДАНИЕ УГЛОВЫХ ТОЧЕК ПОВЕРХНОСТИ ХОРД ===============================

% Угловые точки поверхности хорд будут спроецированы на базовую плоскость
% На проекции поверхности хорд на базовую плоскость будет создано поле распределенной нагрузки

% A1 -> A2 - направление размаха по передней кромке
A1 = [0 0 100];
A2 = [2000 0 100];

% A3 -> A4 - направление размаха по задней кромке
A3 = [0 -400 100];
A4 = [2000 -200 100];


% ======================================== ЗАДАНИЕ СУММАРНОЙ СИЛЫ =======================================

% Суммарная сила, действующая по нормали к базовой плоскости
% Положительное направление нагрузки задается направлением нормали к базовой плоскости
Pn = 3000;


% ====================== ЗАДАНИЕ ЗАКОНА РАСПРЕДЕЛЕНИЯ ПОГОННОЙ НАГРУЗКИ ПО РАЗМАХУ ======================

% Закон распределения погонной нагрузки по размаху
Span_Load_Law = 'TRAPEZOID'; % TRAPEZOID | CHORD_PROPORTIONAL | LOAD_DIAGRAM

                             % TRAPEZOID - распределение по трапеции с заданным центром давления
                             % CHORD_PROPORTIONAL - распределение по трапеции, построенной пропорционально хордам
                             % LOAD_DIAGRAM - эпюра распределения погонной нагрузки по размаху загружается из файла

% ----------------------------------
%   Если Span_Load_Law = TRAPEZOID
% ----------------------------------
    Span_Trapezoid_Zd_Type = 'PARAMETER'; % PARAMETER | LOCATION    % Cпособ задания центра давления по размаху

        % Если Span_Trapezoid_Zd_Type = PARAMETER
            Span_Trapezoid_Zd_Value = 0.4; % Центр давления по размаху задается параметром Zd

        % Если Span_Trapezoid_Zd_Type = LOCATION
            Span_Trapezoid_Zd_Location = [1346.729 248.456 739.358]; % Центр давления по размаху задается координатами точки. Эта точка проецируется на базовую плоскость, после чего ее параметрическая координата по размаху принимается в качестве параметра Zd.

% -------------------------------------------
%   Если Span_Load_Law = CHORD_PROPORTIONAL
% -------------------------------------------
    % Данный закон не имеет настраиваемых параметров

% -------------------------------------
%   Если Span_Load_Law = LOAD_DIAGRAM
% -------------------------------------
    Span_Load_Diagram_File_Name = '_Span_Load_Diagram.txt'; % Имя файла с эпюрой распределения погонной нагрузки по размаху


% =========================== ЗАДАНИЕ ЗАКОНА РАСПРЕДЕЛЕНИЯ ДАВЛЕНИЯ ПО ХОРДАМ ===========================

% Закон распределения давления по хордам
Chord_Pressure_Law = 'TRAPEZOID'; % TRAPEZOID | MODEL_X, где X - число от 1 до 15 | USER_MODEL

                                  % TRAPEZOID - распределение по трапеции
                                  % MODEL_1 | MODEL_6  | MODEL_11
                                  % MODEL_2 | MODEL_7  | MODEL_12
                                  % MODEL_3 | MODEL_8  | MODEL_13   - семейство распределений (см. руководство пользователя)
                                  % MODEL_4 | MODEL_9  | MODEL_14
                                  % MODEL_5 | MODEL_10 | MODEL_15
                                  % USER_MODEL - явное задание эпюр (одна или несколько эпюр распределения давления по хордам загружаются из файла)

% ---------------------------------------
%   Если Chord_Pressure_Law = TRAPEZOID
% ---------------------------------------
    Chord_Trapezoid_Xd_Type = 'PARAMETER'; % PARAMETER | LOCATION | DISTRIBUTION    % Cпособ задания центра давления по хорде

        % Если Chord_Trapezoid_Xd_Type = PARAMETER
            Chord_Trapezoid_Xd_Value = 0.4; % Центр давления по каждой хорде постоянен и задается параметром Xd

        % Если Chord_Trapezoid_Xd_Type = LOCATION
            Chord_Trapezoid_Xd_Location = [1346.729 248.456 739.358]; % Центр давления по каждой хорде постоянен и задается координатами точки. Эта точка проецируется на базовую плоскость, после чего ее параметрическая координата по хорде принимается в качестве параметра Xd для всех хорд.

        % Если Chord_Trapezoid_Xd_Type = DISTRIBUTION
            Chord_Trapezoid_Xd_Distr_File_Name = '_Trapezoid_Xd_Distribution.txt'; % Распределение параметра Xd по размаху загружается из файла

% ---------------------------------------------------------------
%   Если Chord_Pressure_Law = MODEL_X, где X - число от 1 до 15
% ---------------------------------------------------------------
    Chord_Model_X_p2_p1_Type = 'CONSTANT'; % CONSTANT | DISTRIBUTION    % Cпособ задания параметра p2/p1
    
        % Если Chord_Model_X_p2_p1_Type = CONSTANT
            Chord_Model_X_p2_p1_Value = 0.5; % Параметр p2/p1 по каждой хорде постоянен

        % Если Chord_Model_X_p2_p1_Type = DISTRIBUTION
            Chord_Model_X_p2_p1_Distr_File_Name = '_Model_X_p2_p1_Distribution.txt'; % Распределение параметра p2/p1 по размаху загружается из файла

    Chord_Model_X_p3_p1_Type = 'CONSTANT'; % CONSTANT | DISTRIBUTION    % Cпособ задания параметра p3/p1
    
        % Если Chord_Model_X_p3_p1_Type = CONSTANT
            Chord_Model_X_p3_p1_Value = 0.25; % Параметр p3/p1 по каждой хорде постоянен

        % Если Chord_Model_X_p3_p1_Type = DISTRIBUTION
            Chord_Model_X_p3_p1_Distr_File_Name = '_Model_X_p3_p1_Distribution.txt'; % Распределение параметра p3/p1 по размаху загружается из файла
            
    Chord_Model_X_p4_p1_Type = 'CONSTANT'; % CONSTANT | DISTRIBUTION    % Cпособ задания параметра p4/p1
    
        % Если Chord_Model_X_p4_p1_Type = CONSTANT
            Chord_Model_X_p4_p1_Value = 0.125; % Параметр p4/p1 по каждой хорде постоянен

        % Если Chord_Model_X_p4_p1_Type = DISTRIBUTION
            Chord_Model_X_p4_p1_Distr_File_Name = '_Model_X_p4_p1_Distribution.txt'; % Распределение параметра p4/p1 по размаху загружается из файла
            
    Chord_Model_X_f_Type = 'CONSTANT'; % CONSTANT | DISTRIBUTION    % Cпособ задания параметра f

        % Если Chord_Model_X_f_Type = CONSTANT
            Chord_Model_X_f_Value = 0.2; % Параметр f по каждой хорде постоянен

        % Если Chord_Model_X_f_Type = DISTRIBUTION
            Chord_Model_X_f_Distr_File_Name = '_Model_X_f_Distribution.txt'; % Распределение параметра f по размаху загружается из файла
            
    Chord_Model_X_f1_Type = 'CONSTANT'; % CONSTANT | DISTRIBUTION    % Cпособ задания параметра f1

        % Если Chord_Model_X_f1_Type = CONSTANT
            Chord_Model_X_f1_Value = 0.15; % Параметр f1 по каждой хорде постоянен

        % Если Chord_Model_X_f1_Type = DISTRIBUTION
            Chord_Model_X_f1_Distr_File_Name = '_Model_X_f1_Distribution.txt'; % Распределение параметра f1 по размаху загружается из файла
            
    Chord_Model_X_f2_Type = 'CONSTANT'; % CONSTANT | DISTRIBUTION    % Cпособ задания параметра f2

        % Если Chord_Model_X_f2_Type = CONSTANT
            Chord_Model_X_f2_Value = 0.3; % Параметр f2 по каждой хорде постоянен

        % Если Chord_Model_X_f2_Type = DISTRIBUTION
            Chord_Model_X_f2_Distr_File_Name = '_Model_X_f2_Distribution.txt'; % Распределение параметра f2 по размаху загружается из файла
            
% ----------------------------------------
%   Если Chord_Pressure_Law = USER_MODEL
% ----------------------------------------
    Chord_User_Model_File_Name = '_Chord_User_Model.txt'; % Имя файла с эпюрами распределения давления по хордам

    
% ======================================= НАСТРОЙКИ ЭКСТРАПОЛЯЦИИ =======================================

% Если проекция элемента на базовую плоскость лежит вне границ проекции поверхности хорд,
% либо вне интервала, на котором задана эпюра или параметр распределения, то нагрузка
% на такой элемент вычисляется с помощью экстраполяции распределения за заданные пределы.

% Виды экстраполяции:
% CONSTANT - экстраполяция константой, равной значению на конце интервала
% LINEAR - линейная экстраполяция, построенная по двум крайним точкам на конце интервала
% ZERO_VALUE - экстраполяция нулевым значением

% Индексы в обозначениях параметров:
% 0 - экстраполяция в окрестности начала размаха или хорды
% 1 - экстраполяция в окрестности конца размаха или хорды

%                              ЭКСТРАПОЛЯЦИЯ ПОГОННОЙ НАГРУЗКИ В НАПРАВЛЕНИИ РАЗМАХА

% Экстраполяция погонной нагрузки за пределы интервала [0,1] по размаху, а также экстраполяция эпюры погонной нагрузки за пределы ее крайних точек
Span_Load_Extrap_0               = 'CONSTANT'; % CONSTANT | LINEAR | ZERO_VALUE
Span_Load_Extrap_1               = 'CONSTANT'; % CONSTANT | LINEAR | ZERO_VALUE

%                                   ЭКСТРАПОЛЯЦИЯ ДАВЛЕНИЯ В НАПРАВЛЕНИИ ХОРД

% Экстраполяция давления за пределы интервала [0,1] по хорде, а также экстраполяция эпюр распределения давления по хорде за пределы их крайних точек
Chord_Pressure_Extrap_0          = 'CONSTANT'; % CONSTANT | LINEAR | ZERO_VALUE
Chord_Pressure_Extrap_1          = 'CONSTANT'; % CONSTANT | LINEAR | ZERO_VALUE

%                      ЭКСТРАПОЛЯЦИЯ НАБОРА ЭПЮР РАСПРЕДЕЛЕНИЯ ДАВЛЕНИЯ В НАПРАВЛЕНИИ РАЗМАХА

% Экстраполяция набора эпюр распределения давления по хордам за пределы их крайних координат по размаху, а также за пределы интервала [0,1] по размаху
User_Model_Extrap_0              = 'CONSTANT'; % CONSTANT | LINEAR
User_Model_Extrap_1              = 'CONSTANT'; % CONSTANT | LINEAR

%                       ЭКСТРАПОЛЯЦИЯ ПАРАМЕТРОВ МОДЕЛЬНЫХ РАСПРЕДЕЛЕНИЙ В НАПРАВЛЕНИИ РАЗМАХА

% -----------------------------
%   Распределение по трапеции
% -----------------------------

% Экстраполяция параметра Xd в распределении по трапеции за пределы интервала [0,1] по размаху, либо за пределы крайних заданных точек
Trapezoid_Xd_Extrap_0            = 'CONSTANT'; % CONSTANT | LINEAR
Trapezoid_Xd_Extrap_1            = 'CONSTANT'; % CONSTANT | LINEAR

% -----------------------------------------------
%   Распределение X, где X - число от 1 до 15
% -----------------------------------------------

% Экстраполяция параметра p2_p1 за пределы интервала [0,1] по размаху, либо за пределы крайних заданных точек
Model_X_p2_p1_Extrap_0           = 'CONSTANT'; % CONSTANT | LINEAR
Model_X_p2_p1_Extrap_1           = 'CONSTANT'; % CONSTANT | LINEAR

% Экстраполяция параметра p3_p1 за пределы интервала [0,1] по размаху, либо за пределы крайних заданных точек
Model_X_p3_p1_Extrap_0           = 'CONSTANT'; % CONSTANT | LINEAR
Model_X_p3_p1_Extrap_1           = 'CONSTANT'; % CONSTANT | LINEAR

% Экстраполяция параметра p4_p1 за пределы интервала [0,1] по размаху, либо за пределы крайних заданных точек
Model_X_p4_p1_Extrap_0           = 'CONSTANT'; % CONSTANT | LINEAR
Model_X_p4_p1_Extrap_1           = 'CONSTANT'; % CONSTANT | LINEAR

% Экстраполяция параметра f за пределы интервала [0,1] по размаху, либо за пределы крайних заданных точек
Model_X_f_Extrap_0               = 'CONSTANT'; % CONSTANT | LINEAR
Model_X_f_Extrap_1               = 'CONSTANT'; % CONSTANT | LINEAR

% Экстраполяция параметра f1 за пределы интервала [0,1] по размаху, либо за пределы крайних заданных точек
Model_X_f1_Extrap_0              = 'CONSTANT'; % CONSTANT | LINEAR
Model_X_f1_Extrap_1              = 'CONSTANT'; % CONSTANT | LINEAR

% Экстраполяция параметра f2 за пределы интервала [0,1] по размаху, либо за пределы крайних заданных точек
Model_X_f2_Extrap_0              = 'CONSTANT'; % CONSTANT | LINEAR
Model_X_f2_Extrap_1              = 'CONSTANT'; % CONSTANT | LINEAR


% =================================== НАСТРОЙКИ СУММИРОВАНИЯ НАГРУЗОК ===================================

% Суммирование нагрузок используется для проверки фактической нагрузки, приходящей на элементы.

% Точка суммирования
Summation_Point = [-100 -50 0]; % Необходима для вычисления результирующего момента

% Прямоугольная система координат для компонент результирующей силы и результирующего момента
Coord_Origin = [0 0 0];         % Начало системы координат
Point_On_Axis_3 = [0 0 1];      % Точка на оси Z
Point_On_Plane_13 = [1 0 0];    % Точка в плоскости XZ


% ==================================== НАСТРОЙКИ КОРРЕКЦИИ НАГРУЗОК =====================================

Correction_Coefficient = 1; % Поправочный коэффициент, на который будет умножена приходящая на элементы нагрузка


% ======================================= НАСТРОЙКИ ПОЛЯ НАГРУЗОК =======================================

Distributed_Load_Mode            = 'CID_DISTR_LOAD'; % CID_DISTR_LOAD | PRESSURE    % Способ задания распределенной нагрузки в Patran:
                                                                                    %
                                                                                    %     CID_DISTR_LOAD - в Patran реализуется нагружение типа CID Distributed Load. Программа Aero Load создаст векторное поле распределенной нагрузки,
                                                                                    %                      ассоциированное с элементами. Векторное поле будет иметь одну ненулевую компоненту и соответствовать системе координат, одна из осей
                                                                                    %                      которой сонаправлена с нормалью к базовой плоскости. Такая система координат должна существовать в базе Patran и использоваться для нагружения.
                                                                                    %                      Таким образом, на элементы будет приложена только нагрузка Pn, направленная по нормали к базовой плоскости и распределенная по указанному закону.
                                                                                    %
                                                                                    %           PRESSURE - в Patran реализуется нагружение типа Pressure. Программа Aero Load создаст скалярное поле давления, ассоциированное с элементами.
                                                                                    %                      При нагружении данное поле необходимо указывать в качестве Top Surface Pressure. На каждый элемент будет приложена нагрузка,
                                                                                    %                      направленная по его нормали. Проекция полученной нагрузки на нормаль к базовой плоскости будет иметь требуемый закон распределения и
                                                                                    %                      суммарную величину Pn. Кроме этого в модели также может возникнуть некоторая побочная нагрузка, тангенциальная к базовой плоскости.
                                                                                    %                      Эта нагрузка может повлиять на реакции в узлах навески и шарнирный момент, поэтому данный способ нагружения следует использовать с осторожностью.
% Если Distributed_Load_Mode = CID_DISTR_LOAD
    Vector_Field_Component       = 3; % 1 | 2 | 3              % Номер ненулевой компоненты векторного поля в случае нагружения через CID Distributed Load

% Если Output_File_Format = SES, либо BOTH
    Field_Name                   = 'Field_from_Aero_Load';     % Имя поля, которое будет создано в Patran при проигрывании сессионного файла


% =======================================================================================================

%                                   ###################################
%                                   ##   КОНЕЦ НАСТРОЕК НАГРУЖЕНИЯ   ##
%                                   ###################################

% #######################################################################################################
% ##                                                                                                   ##
% ##                                     КОНЕЦ НАСТРОЕК ПРОГРАММЫ                                      ##
% ##                                                                                                   ##
% #######################################################################################################

% Проверка параметра Need_Reading_BDF_File
switch Need_Reading_BDF_File
    case {'TRUE', 'FALSE'}
        % Допустимые значения
    otherwise
        fprintf (1, 'Недопустимое значение параметра Need_Reading_BDF_File !\n');
        fprintf (1, 'Разрешенные значения: TRUE, FALSE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        return;
end

% Проверка параметра Model_length_unit
switch Model_length_unit
    case {'mm', 'm', 'inch', 'ft'}
        % Допустимые значения
    otherwise
        fprintf (1, 'Недопустимое значение параметра Model_length_unit !\n');
        fprintf (1, 'Разрешенные значения: mm, m, inch, ft\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        return;
end

% Очистка памяти
if (strcmp(Need_Reading_BDF_File, 'TRUE'))
    
    clear DB_NODES;
    clear DB_ELEMENTS;
    clear DB_MPC;
    clear DB_MATERIALS;
    clear DB_PSETS;
    clear DB_COORD;
    clear DB_FIELDS;
    
    clear AT_NODES;
    clear AT_ELEMENTS;
    clear AT_MPC;
    clear AT_MATERIALS;
    clear AT_PSETS;
    clear AT_COORD;
    clear AT_FIELDS;
    
end

% -----------------------------------------------

global software_version; %                      1
global software_date; %                         1
global software_year; %                         1

global ErrCode; %                               1
global Progress_Bar_Segments; %                 1
global Progress_Bar_Delay; %                    1
global Progress_Bar_Elm_Threshold; %            1

global MAT2_orthotropic_tolerance_multiplier; % 1
global MAT9_orthotropic_tolerance_multiplier; % 1
global MAT2_C_zero_det_tolerance; %             1
global MAT9_C_zero_det_tolerance; %             1
global Laminate_offset_round_tolerance; %       1
global Orientation_Vector_zero_tolerance; %     1
global Global_equivalence_tolerance; %          1
global Field_Zero_Record_Tolerance; %           1
global Field_Nonzero_Record_Tolerance; %        1

global DB_NODES; %                              1
global DB_ELEMENTS; %                           1
global DB_MPC; %                                1
global DB_MATERIALS; %                          1
global DB_PSETS; %                              1
global DB_COORD; %                              1
global DB_FIELDS; %                             1

global AT_NODES; %                              1
global AT_ELEMENTS; %                           1
global AT_MPC; %                                1
global AT_MATERIALS; %                          1
global AT_PSETS; %                              1
global AT_COORD; %                              1
global AT_FIELDS; %                             1

global AT_Page_Prealloc_Size; %                 1
global db_Next_Field_Number; %                  1
global BDF_Entity_Read_Settings; %              1

% -----------------------------------------------

global Cross_Product_Vector_zero_tolerance;
global db_Next_Coord_Number;

global ELEMENT_AREAS;
global PROJECTED_NODES;

global Stair_Parameter;

global Graphic_Window_Handle;
global Graphics_Properties;
global Graphics;

global Icons_16;
global Icons_26;

global ELEMENT_FORCES;
global ELEMENT_NORMAL_PROJECTIONS;

% -----------------------------------------------

ErrCode = 0;

software_version = []; %                        1
software_date = []; %                           1
software_year = []; %                           1

Progress_Bar_Segments = []; %                   1
Progress_Bar_Delay = []; %                      1
Progress_Bar_Elm_Threshold = []; %              1

MAT2_orthotropic_tolerance_multiplier = []; %   1
MAT9_orthotropic_tolerance_multiplier = []; %   1
MAT2_C_zero_det_tolerance = []; %               1
MAT9_C_zero_det_tolerance = []; %               1
Laminate_offset_round_tolerance = []; %         1
Orientation_Vector_zero_tolerance = []; %       1
Global_equivalence_tolerance = []; %            1
Field_Zero_Record_Tolerance = []; %             1
Field_Nonzero_Record_Tolerance = []; %          1

AT_Page_Prealloc_Size = []; %                   1

Cross_Product_Vector_zero_tolerance = [];

PROJECTED_NODES = [];

Stair_Parameter = [];

if (strcmp(Need_Reading_BDF_File, 'TRUE')) % Когда читается bdf файл

    DB_FIELDS = []; %                               1
    AT_FIELDS = []; %                               1
    
    BDF_Entity_Read_Settings = []; %                1

    db_Next_Field_Number = 1; %                     1
    db_Next_Coord_Number = [];
    
    ELEMENT_AREAS = [];
    
    Graphic_Window_Handle = [];
    Graphics_Properties = [];
    Graphics = [];
    
    Icons_16 = [];
    Icons_26 = [];
    
    Previous_Language = [];
    
end

ELEMENT_FORCES = [];
ELEMENT_NORMAL_PROJECTIONS = [];

% -----------------------------------------------

% Отсчет времени выполнения программы
tic;

% Инициализация базовых переменных
Init_Variables ();

% Инициализация допусков
Init_Tolerances (Model_length_unit);

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

% Печать приветствия
Print_Greeting ();

% Проверка параметров ввода-вывода
switch Output_File_Format
    case {'SES', 'CSV', 'BOTH', 'OFF'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра Output_File_Format !\n');
        fprintf (1, 'Разрешенные значения: SES, CSV, BOTH, OFF\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch Write_Current_Config
    case {'TRUE', 'FALSE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра Write_Current_Config !\n');
        fprintf (1, 'Разрешенные значения: TRUE, FALSE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch Load_Visualization
    case {'TRUE', 'FALSE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра Load_Visualization !\n');
        fprintf (1, 'Разрешенные значения: TRUE, FALSE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch Window_Language
    case {'RU', 'EN'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра Window_Language !\n');
        fprintf (1, 'Разрешенные значения: RU, EN\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch Settings_Source
    case {'PROGRAM_TEXT', 'CONFIG_FILE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра Settings_Source !\n');
        fprintf (1, 'Разрешенные значения: PROGRAM_TEXT, CONFIG_FILE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

% Транспонирование векторных переменных в случае настроек из текста программы
if (strcmp(Settings_Source, 'PROGRAM_TEXT'))
    
    if (~iscolumn(Z0))
        Z0 = Z0';
    end

    if (~iscolumn(Z1))
        Z1 = Z1';
    end

    if (~iscolumn(D1))
        D1 = D1';
    end

    if (~iscolumn(D2))
        D2 = D2';
    end

    if (~iscolumn(D3))
        D3 = D3';
    end

    if (~iscolumn(A1))
        A1 = A1';
    end

    if (~iscolumn(A2))
        A2 = A2';
    end

    if (~iscolumn(A3))
        A3 = A3';
    end

    if (~iscolumn(A4))
        A4 = A4';
    end
    
    if (~iscolumn(Span_Trapezoid_Zd_Location))
        Span_Trapezoid_Zd_Location = Span_Trapezoid_Zd_Location';
    end
    
    if (~iscolumn(Chord_Trapezoid_Xd_Location))
        Chord_Trapezoid_Xd_Location = Chord_Trapezoid_Xd_Location';
    end

    if (~iscolumn(Summation_Point))
        Summation_Point = Summation_Point';
    end

    if (~iscolumn(Coord_Origin))
        Coord_Origin = Coord_Origin';
    end

    if (~iscolumn(Point_On_Axis_3))
        Point_On_Axis_3 = Point_On_Axis_3';
    end

    if (~iscolumn(Point_On_Plane_13))
        Point_On_Plane_13 = Point_On_Plane_13';
    end
    
end

% Создание структуры с настройками нагружения в случае настроек из текста программы
if (strcmp(Settings_Source, 'PROGRAM_TEXT'))
    
    Load = [];
    
    Load.Basic_Plane.Definition = Basic_Plane_Definition;
    Load.Basic_Plane.Z0 = Z0;
    Load.Basic_Plane.Z1 = Z1;
    Load.Basic_Plane.D1 = D1;
    Load.Basic_Plane.D2 = D2;
    Load.Basic_Plane.D3 = D3;
    Load.Basic_Plane.Equation = [];

    Load.Chord_Surface.A1 = A1;
    Load.Chord_Surface.A2 = A2;
    Load.Chord_Surface.A3 = A3;
    Load.Chord_Surface.A4 = A4;
    Load.Chord_Surface.A1_projected = [];
    Load.Chord_Surface.A2_projected = [];
    Load.Chord_Surface.A3_projected = [];
    Load.Chord_Surface.A4_projected = [];

    Load.Pn = Pn;
    Load.Vector = [];

    Load.Span_Load.Law = Span_Load_Law;
    
    Load.Span_Load.Trapezoid_Zd_Type = Span_Trapezoid_Zd_Type;
    Load.Span_Load.Trapezoid_Zd_Value = Span_Trapezoid_Zd_Value;
    Load.Span_Load.Trapezoid_Zd_Location = Span_Trapezoid_Zd_Location;
    
    Load.Span_Load.Load_Diagram_File_Name = Span_Load_Diagram_File_Name;
    Load.Span_Load.Load_Diagram_Data = [];
    Load.Span_Load.Load_Diagram_Initial_Data = [];

    Load.Chord_Pressure.Law = Chord_Pressure_Law;
    
    Load.Chord_Pressure.Trapezoid_Xd_Type = Chord_Trapezoid_Xd_Type;
    Load.Chord_Pressure.Trapezoid_Xd_Value = Chord_Trapezoid_Xd_Value;
    Load.Chord_Pressure.Trapezoid_Xd_Location = Chord_Trapezoid_Xd_Location;
    Load.Chord_Pressure.Trapezoid_Xd_Distr_File_Name = Chord_Trapezoid_Xd_Distr_File_Name;
    Load.Chord_Pressure.Trapezoid_Xd_Distr_Data = [];
    Load.Chord_Pressure.Trapezoid_Xd_Distr_Initial_Data = [];
    
    Load.Chord_Pressure.Model_X_p2_p1_Type = Chord_Model_X_p2_p1_Type;
    Load.Chord_Pressure.Model_X_p2_p1_Value = Chord_Model_X_p2_p1_Value;
    Load.Chord_Pressure.Model_X_p2_p1_Distr_File_Name = Chord_Model_X_p2_p1_Distr_File_Name;
    Load.Chord_Pressure.Model_X_p2_p1_Distr_Data = [];
    Load.Chord_Pressure.Model_X_p2_p1_Distr_Initial_Data = [];
    
    Load.Chord_Pressure.Model_X_p3_p1_Type = Chord_Model_X_p3_p1_Type;
    Load.Chord_Pressure.Model_X_p3_p1_Value = Chord_Model_X_p3_p1_Value;
    Load.Chord_Pressure.Model_X_p3_p1_Distr_File_Name = Chord_Model_X_p3_p1_Distr_File_Name;
    Load.Chord_Pressure.Model_X_p3_p1_Distr_Data = [];
    Load.Chord_Pressure.Model_X_p3_p1_Distr_Initial_Data = [];
    
    Load.Chord_Pressure.Model_X_p4_p1_Type = Chord_Model_X_p4_p1_Type;
    Load.Chord_Pressure.Model_X_p4_p1_Value = Chord_Model_X_p4_p1_Value;
    Load.Chord_Pressure.Model_X_p4_p1_Distr_File_Name = Chord_Model_X_p4_p1_Distr_File_Name;
    Load.Chord_Pressure.Model_X_p4_p1_Distr_Data = [];
    Load.Chord_Pressure.Model_X_p4_p1_Distr_Initial_Data = [];
    
    Load.Chord_Pressure.Model_X_f_Type = Chord_Model_X_f_Type;
    Load.Chord_Pressure.Model_X_f_Value = Chord_Model_X_f_Value;
    Load.Chord_Pressure.Model_X_f_Distr_File_Name = Chord_Model_X_f_Distr_File_Name;
    Load.Chord_Pressure.Model_X_f_Distr_Data = [];
    Load.Chord_Pressure.Model_X_f_Distr_Initial_Data = [];
    
    Load.Chord_Pressure.Model_X_f1_Type = Chord_Model_X_f1_Type;
    Load.Chord_Pressure.Model_X_f1_Value = Chord_Model_X_f1_Value;
    Load.Chord_Pressure.Model_X_f1_Distr_File_Name = Chord_Model_X_f1_Distr_File_Name;
    Load.Chord_Pressure.Model_X_f1_Distr_Data = [];
    Load.Chord_Pressure.Model_X_f1_Distr_Initial_Data = [];
    
    Load.Chord_Pressure.Model_X_f2_Type = Chord_Model_X_f2_Type;
    Load.Chord_Pressure.Model_X_f2_Value = Chord_Model_X_f2_Value;
    Load.Chord_Pressure.Model_X_f2_Distr_File_Name = Chord_Model_X_f2_Distr_File_Name;
    Load.Chord_Pressure.Model_X_f2_Distr_Data = [];
    Load.Chord_Pressure.Model_X_f2_Distr_Initial_Data = [];
    
    Load.Chord_Pressure.User_Model_File_Name = Chord_User_Model_File_Name;
    Load.Chord_Pressure.User_Model_Data = [];
    Load.Chord_Pressure.User_Model_Initial_Data = [];

    Load.Extrapolation.Span_Load_0 = Span_Load_Extrap_0;
    Load.Extrapolation.Span_Load_1 = Span_Load_Extrap_1;
    Load.Extrapolation.Chord_Pressure_0 = Chord_Pressure_Extrap_0;
    Load.Extrapolation.Chord_Pressure_1 = Chord_Pressure_Extrap_1;
    Load.Extrapolation.User_Model_0 = User_Model_Extrap_0;
    Load.Extrapolation.User_Model_1 = User_Model_Extrap_1;
    Load.Extrapolation.Trapezoid_Xd_0 = Trapezoid_Xd_Extrap_0;
    Load.Extrapolation.Trapezoid_Xd_1 = Trapezoid_Xd_Extrap_1;
    Load.Extrapolation.Model_X_p2_p1_0 = Model_X_p2_p1_Extrap_0;
    Load.Extrapolation.Model_X_p2_p1_1 = Model_X_p2_p1_Extrap_1;
    Load.Extrapolation.Model_X_p3_p1_0 = Model_X_p3_p1_Extrap_0;
    Load.Extrapolation.Model_X_p3_p1_1 = Model_X_p3_p1_Extrap_1;
    Load.Extrapolation.Model_X_p4_p1_0 = Model_X_p4_p1_Extrap_0;
    Load.Extrapolation.Model_X_p4_p1_1 = Model_X_p4_p1_Extrap_1;
    Load.Extrapolation.Model_X_f_0 = Model_X_f_Extrap_0;
    Load.Extrapolation.Model_X_f_1 = Model_X_f_Extrap_1;
    Load.Extrapolation.Model_X_f1_0 = Model_X_f1_Extrap_0;
    Load.Extrapolation.Model_X_f1_1 = Model_X_f1_Extrap_1;
    Load.Extrapolation.Model_X_f2_0 = Model_X_f2_Extrap_0;
    Load.Extrapolation.Model_X_f2_1 = Model_X_f2_Extrap_1;

    Load.Summation_Point = Summation_Point;

    Load.Coord_Origin = Coord_Origin;
    Load.Point_On_Axis_3 = Point_On_Axis_3;
    Load.Point_On_Plane_13 = Point_On_Plane_13;

    Load.Correction_Coefficient = Correction_Coefficient;

    Load.Distributed_Load_Mode = Distributed_Load_Mode;
    Load.Vector_Field_Component = Vector_Field_Component;
    Load.Field_Name = Field_Name;
    
    Load.Precomputed_Data = [];
    
end

% Чтение конфигурационного файла
if (strcmp(Settings_Source, 'CONFIG_FILE'))
    
    % Корректировка Config_File_Directory
    if (Config_File_Directory(length(Config_File_Directory)) == '\')
        Config_File_Directory = Config_File_Directory(1:length(Config_File_Directory)-1);
    end

    % Корректировка имени конфигурационного файла
    if ((length(Config_File_Name) > 6) && strcmpi(Config_File_Name(length(Config_File_Name)-5:length(Config_File_Name)), '.alcfg'))
        Config_File_Name = Config_File_Name(1:length(Config_File_Name)-6);
    end

    % Чтение конфигурационного файла
    Load = Read_Config(Config_File_Directory, Config_File_Name);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end
    
end

% Проверка настроек нагружения
Check_Load_Settings(Load, Settings_Source);

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

% Чтение эпюр распределений в случае настроек из текста программы
if (strcmp(Settings_Source, 'PROGRAM_TEXT'))
    
    % Чтение эпюр при необходимости
    Load = Read_Distributions(Load);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end
    
end

% Работа с распределениями в случае конфигурационного файла
if (strcmp(Settings_Source, 'CONFIG_FILE'))
    
    % Проверка наличия необходимых распределений и удаление неиспользуемых распределений
    Load = Process_CFG_Distributions(Load);
    
    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end
    
end

% Проверка эпюр (соблюдение правил в файлах с эпюрами)
Check_Distributions(Load);

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

% Копирование исходных эпюр
Load.Span_Load.Load_Diagram_Initial_Data = Load.Span_Load.Load_Diagram_Data;
Load.Chord_Pressure.Trapezoid_Xd_Distr_Initial_Data = Load.Chord_Pressure.Trapezoid_Xd_Distr_Data;
Load.Chord_Pressure.Model_X_p2_p1_Distr_Initial_Data = Load.Chord_Pressure.Model_X_p2_p1_Distr_Data;
Load.Chord_Pressure.Model_X_p3_p1_Distr_Initial_Data = Load.Chord_Pressure.Model_X_p3_p1_Distr_Data;
Load.Chord_Pressure.Model_X_p4_p1_Distr_Initial_Data = Load.Chord_Pressure.Model_X_p4_p1_Distr_Data;
Load.Chord_Pressure.Model_X_f_Distr_Initial_Data = Load.Chord_Pressure.Model_X_f_Distr_Data;
Load.Chord_Pressure.Model_X_f1_Distr_Initial_Data = Load.Chord_Pressure.Model_X_f1_Distr_Data;
Load.Chord_Pressure.Model_X_f2_Distr_Initial_Data = Load.Chord_Pressure.Model_X_f2_Distr_Data;
Load.Chord_Pressure.User_Model_Initial_Data = Load.Chord_Pressure.User_Model_Data;

% Расширение эпюр до границ отрезка [0,1]
Load = Extend_Distributions(Load);

% Проверка параметров распределений
Check_Distr_Parameters(Load, Settings_Source);

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

% Проверка интегралов эпюр
Check_Distr_Integrals(Load);

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

% Корректировка Work_Directory
if (Work_Directory(length(Work_Directory)) == '\')
    Work_Directory = Work_Directory(1:length(Work_Directory)-1);
end

% Корректировка имени bdf файла
if ((length(Input_BDF_name) > 4) && strcmpi(Input_BDF_name(length(Input_BDF_name)-3:length(Input_BDF_name)), '.bdf'))
    Input_BDF_name = Input_BDF_name(1:length(Input_BDF_name)-4);
end

% ======== Этап создания модели ========

if (strcmp(Need_Reading_BDF_File, 'TRUE'))

    fprintf (1, 'СОЗДАНИЕ МОДЕЛИ\n\n');

    % Чтение bdf файла

    [DB_NODES, ELEMENTS, MPC, MATERIALS, PSETS, COORD, BDF_File_Path, N_BDF_Strings] = Read_BDF(Work_Directory, Input_BDF_name);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end

    % Создание адресных таблиц

    [AT_COORD, AT_NODES, AT_MPC, AT_MATERIALS, AT_ELEMENTS, AT_PSETS] = Create_Address_Tables(COORD, MPC, MATERIALS, ELEMENTS, PSETS);

     if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end

    % --- Проверка объектов ---

    % Проверка узлов

    if (~isempty(DB_NODES))

        Check_Nodes();

        if (ErrCode < 0)
            fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
            toc;
            return;
        end

    end

    % Проверка MPC

    if (~isempty(MPC))

        Check_MPC(MPC);

        if (ErrCode < 0)
            fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
            toc;
            return;
        end

    end

    % Проверка материалов

    if (~isempty(MATERIALS))

        Check_Materials(MATERIALS);

        if (ErrCode < 0)
            fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
            toc;
            return;
        end

    end

    % Проверка property sets

    if (~isempty(PSETS))

        Check_Psets(PSETS, MATERIALS, COORD);

        if (ErrCode < 0)
            fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
            toc;
            return;
        end

    end

    % Проверка элементов

    if (~isempty(ELEMENTS))

        Check_Elements(ELEMENTS, PSETS, COORD);

        if (ErrCode < 0)
            fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
            toc;
            return;
        end

    end

    % --- Обработка объектов и создание баз данных ---

    % Обработка систем координат

    if (~isempty(COORD))

        DB_COORD = Create_DB_COORD(COORD);

        if (ErrCode < 0)
            fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
            toc;
            return;
        end

        clear COORD;

    end

    % Обработка узлов

    if (~isempty(DB_NODES))

        Fill_DB_NODES_Locations();

        if (ErrCode < 0)
            fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
            toc;
            return;
        end

        clear NODES;

    end

    % Обработка MPC

    if (~isempty(MPC))

        DB_MPC = Create_DB_MPC(MPC);

        if (ErrCode < 0)
            fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
            toc;
            return;
        end

        clear MPC;

    end

    % Обработка материалов

    if (~isempty(MATERIALS))

        DB_MATERIALS = Create_DB_MATERIALS(MATERIALS);

        if (ErrCode < 0)
            fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
            toc;
            return;
        end

        clear MATERIALS;

    end

    % Обработка property sets

    if (~isempty(PSETS))

        DB_PSETS = Create_DB_PSETS(PSETS);

        if (ErrCode < 0)
            fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
            toc;
            return;
        end

        clear PSETS;

    end

    % Обработка элементов

    if (~isempty(ELEMENTS))

        DB_ELEMENTS = Create_DB_ELEMENTS(ELEMENTS);

        if (ErrCode < 0)
            fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
            toc;
            return;
        end

        clear ELEMENTS;

    end

    % --- Вывод статистики ---

    fprintf (1, '\nСтатистика модели:\n\n');

    if (strcmp(BDF_Entity_Read_Settings.Read_NODES, 'ON'))
        fprintf (1, '               Узлов: %i\n', size(DB_NODES,1));
    end

    if (strcmp(BDF_Entity_Read_Settings.Read_PSETS_ELEMENTS, 'ON'))
        fprintf (1, '           Элементов: %i\n', size(DB_ELEMENTS,1));
    end

    if (strcmp(BDF_Entity_Read_Settings.Read_MPC, 'ON'))
        fprintf (1, '                 MPC: %i\n', size(DB_MPC,1));
    end

    if (strcmp(BDF_Entity_Read_Settings.Read_MATERIALS, 'ON'))
        fprintf (1, '          Материалов: %i\n', size(DB_MATERIALS,1));
    end

    if (strcmp(BDF_Entity_Read_Settings.Read_PSETS_ELEMENTS, 'ON'))
        fprintf (1, '       Property sets: %i\n', size(DB_PSETS,1));
    end

    if (strcmp(BDF_Entity_Read_Settings.Read_COORD, 'ON'))
        fprintf (1, '    Систем координат: %i\n', size(DB_COORD,1));
    end

    Print_Delimiter();

end


% ------------------------------------------------ ФОРМАТ ГЛОБАЛЬНЫХ БАЗ ДАННЫХ ------------------------------------------------

% DB_NODES | .ID | .Ref_Location(3,1) | .Location(3,1) | .Reference_CID | .Analysis_CID |

% DB_ELEMENTS (Tet | Wedge | Hex) | .type | .ID | .Prop_ID | .N_nodes | .Nodes(N_nodes,1) |
% DB_ELEMENTS (Quad | Tria)       | .type | .ID | .Prop_ID | .N_nodes | .Nodes(N_nodes,1) |
% DB_ELEMENTS (Bar)               | .type | .ID | .Prop_ID | .N_nodes | .Nodes(N_nodes,1) |

% DB_MPC (RBAR) | .type | .ID | .ind_grid | .ind_DOF (в СК анализа узла ind) | .dep_grid | .dep_DOF (в СК анализа узла dep) |
% DB_MPC (RBE2) | .type | .ID | .ind_grid | .dep_grid(:,1) | .dep_DOF (в СК анализа узлов dep) |
% DB_MPC (RBE3) | .type | .ID | .ind_data(:,3) | .dep_grid | .dep_DOF (в СК анализа узла dep) |
%            .ind_data(i,:) | weight_i | ind_grid_i | dof_i (в СК анализа узла ind_grid_i) |

% DB_MATERIALS (isotropic)      | .type | .ID | .Patran_name | .E | .nu |
% DB_MATERIALS (2d_orthotropic) | .type | .ID | .Patran_name | .E1 | .E2 | .nu12 | .G12 |
% DB_MATERIALS (2d_anisotropic) | .type | .ID | .Patran_name | .C(3,3) - матрица Гука |                                         ### Сдвиговые деформации инженерные
% DB_MATERIALS (3d_orthotropic) | .type | .ID | .Patran_name | .E1 | .E2 | .E3 | .G12 | .G23 | .G13 | .nu12 | .nu23 | .nu13 |   ### nu12*E2 = nu21*E1 # nu23*E3 = nu32*E2 # nu13*E3 = nu31*E1
% DB_MATERIALS (3d_anisotropic) | .type | .ID | .Patran_name | .C(6,6) - матрица Гука |                                         ### Сдвиговые деформации инженерные # Расшифровка номеров сдвиговых компонент: 4 - 12, 5 - 23, 6 - 13 # nu12*E2 = nu21*E1 # nu23*E3 = nu32*E2 # nu13*E3 = nu31*E1
% DB_MATERIALS (pshell_MAT2_for_transverse_shear) | .type | .ID | .Patran_name | .C(2,2) - матрица Гука |

% DB_PSETS ( PSOLID) | .type | .ID | .Patran_name | .Mat_ID | .Ori_CID (-1, если element coordinate system) |
% DB_PSETS ( PCOMP)  | .type | .ID | .Patran_name | .Patran_laminate_name | .N_plies | .Laminate(:,3) | .Laminate_offset |
%                    | .Ori_Field_ID | .Offset_Field_ID |         DB_FIELDS{Ori_Field_ID}.Value_data(:,2) [Value_data(j,1) - ori_type: (0 - CID | 1 - Angle)] [Value_data(j,2) - ori_data]
%             .Laminate(i,3) | Mat_ID_i | t_i | Theta_i |
% DB_PSETS ( PCOMPG) | .type | .ID | .Patran_name | .Patran_laminate_name | .N_plies | .Laminate(:,4) | .Laminate_offset |
%                    | .Ori_Field_ID | .Offset_Field_ID |         DB_FIELDS{Ori_Field_ID}.Value_data(:,2) [Value_data(j,1) - ori_type: (0 - CID | 1 - Angle)] [Value_data(j,2) - ori_data]
%             .Laminate(i,4) | Mat_ID_i | t_i | Theta_i | Global_ply_ID_i |
% DB_PSETS ( PSHELL) | .type | .ID | .Patran_name | .Mat_ID_membrane | .Mat_ID_bending | .Mat_ID_transverse_shear | .t |
%                    | .Ori_Field_ID | .Offset_Field_ID |         DB_FIELDS{Ori_Field_ID}.Value_data(:,2) [Value_data(j,1) - ori_type: (0 - CID | 1 - Angle)] [Value_data(j,2) - ori_data]
% DB_PSETS (  PBUSH) | .type | .ID | .Patran_name | .K(6,1) | .Ori_CID_Field_ID |
% DB_PSETS (   PROD) | .type | .ID | .Patran_name | .Mat_ID | .Area | .J |
% DB_PSETS (PBMSECT) | .type | .ID | .Patran_name | .Mat_ID | .Cross_section_form | .Section_data |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
% DB_PSETS (PBRSECT) | .type | .ID | .Patran_name | .Mat_ID | .Cross_section_form | .Section_data |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
% DB_PSETS (   PBAR) | .type | .ID | .Patran_name | .Mat_ID | .Area | .I1 | .I2 | .I12 | .J | .K1 | .K2 |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
% DB_PSETS (  PBARL) | .type | .ID | .Patran_name | .Mat_ID | .Shape | .Dim(:,1) |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
%             .Shape = (ROD, TUBE, TUBE2, L, I, CHAN, T, BOX, BAR, CROSS, H, T1, I1, CHAN1, Z, CHAN2, T2, BOX1, HEXA, HAT, HAT1, DBOX )
% DB_PSETS (  PBEAM) | .type | .ID | .Patran_name | .Mat_ID | .Area | .I1 | .I2 | .I12 | .J | .K1 | .K2 | .S1 | .S2 | .N1_A | .N2_A | .N1_B | .N2_B |
%                    | .N_intermediate_states | .Intermediate_states_data{N_intermediate_states,1} |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
%             .Intermediate_states_data{i} : { .Location | .A | .I1 | .I2 | .I12 | .J }
% DB_PSETS ( PBEAML) | .type | .ID | .Patran_name | .Mat_ID | .Shape | .Dim(:,1) | .N_intermediate_states | .Intermediate_states_data{N_intermediate_states,1} |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
%             .Intermediate_states_data{i} : { .Location | .Dim(:,1) }
%             .Shape = (ROD, TUBE, TUBE2, L, I, CHAN, T, BOX, BAR, CROSS, H, T1, I1, CHAN1, Z, CHAN2, T2, BOX1, HEXA, HAT, HAT1, DBOX )
% DB_PSETS ( PBCOMP) | .type | .ID | .Patran_name | .Mat_ID | .Area | .I1 | .I2 | .I12 | .J | .K1 | .K2 | .N1 | .N2 | .SYMOPT | .N_lumped_areas | .Lumped_area_data{N_lumped_areas,1} |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
%             .Lumped_area_data{i} : { .Y | .Z | .C | .MID }

% DB_COORD | .ID | .type (Rectangular | Cylindrical) | .e_x (.e_r) | .e_y(.e_t) | .e_z | .origin |

% DB_FIELDS | .ID | .Dim | .Default | .AT{:,1} | .ID_data{:,1} | .Value_data{:,1} |

% ------------------------------------------------------------------------------------------------------------------------------

% -------------------------------------------------- ПЕРЕЧЕНЬ АДРЕСНЫХ ТАБЛИЦ --------------------------------------------------

% AT_NODES(:,1)
% AT_ELEMENTS(:,1)
% AT_MPC(:,1)
% AT_MATERIALS(:,1)
% AT_PSETS(:,1)
% AT_COORD(:,1)
% AT_FIELDS(:,1)

% ------------------------------------------------------------------------------------------------------------------------------

% ----------------------------------------- ФУНКЦИИ ДЛЯ ДОСТУПА К СВОЙСТВАМ ЭЛЕМЕНТОВ ------------------------------------------

%               [Ori_type, Ori_data] = Get_Shell_Orientation(Element_ID)
%                             Offset = Get_Shell_Offset(Element_ID)    (см. описание функции)
%                             Offset = Get_Plate_Offset(Element_ID)    (см. описание функции)
%                            Ori_CID = Get_Bush_Ori_CID(Element_ID)
%                         Ori_vector = Get_Bar_Ori_Vector(Element_ID)
% [Offset_vector_A, Offset_vector_B] = Get_Bar_Offset_Vectors(Element_ID)
%     [Pinned_DOFs_A, Pinned_DOFs_B] = Get_Bar_Pinned_DOFs(Element_ID)

% ------------------------------------------------------------------------------------------------------------------------------


% ##############################################################################################################################
% ##                                                                                                                          ##
% ##   С ЭТОГО МОМЕНТА НА ОСНОВЕ ДАННОГО КОДА МОЖНО СОЗДАВАТЬ ДРУГИЕ ПРОГРАММЫ, ИСПОЛЬЗУЮЩИЕ ДАННЫЕ ИЗ СФОРМИРОВАННОЙ БАЗЫ    ##
% ##                                                                                                                          ##
% ##############################################################################################################################


% ======== Этап нагружения модели ========

fprintf (1, 'НАГРУЖЕНИЕ МОДЕЛИ\n\n');

[CID_DISTR_LOAD_FIELD, PRESSURE_FIELD, Load] = Loading_Process(Load, Need_Reading_BDF_File, Settings_Source);

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

Print_Delimiter();


% -------------------------------------------------- ОПИСАНИЕ СТРУКТУРЫ Load ---------------------------------------------------

% Load.Basic_Plane.Definition
% Load.Basic_Plane.Z0
% Load.Basic_Plane.Z1
% Load.Basic_Plane.D1
% Load.Basic_Plane.D2
% Load.Basic_Plane.D3
% Load.Basic_Plane.Equation
% 
% Load.Chord_Surface.A1
% Load.Chord_Surface.A2
% Load.Chord_Surface.A3
% Load.Chord_Surface.A4
% Load.Chord_Surface.A1_projected
% Load.Chord_Surface.A2_projected
% Load.Chord_Surface.A3_projected
% Load.Chord_Surface.A4_projected
% 
% Load.Pn
% Load.Vector
% 
% Load.Span_Load.Law
% 
% Load.Span_Load.Trapezoid_Zd_Type
% Load.Span_Load.Trapezoid_Zd_Value
% Load.Span_Load.Trapezoid_Zd_Location
% 
% Load.Span_Load.Load_Diagram_File_Name
% Load.Span_Load.Load_Diagram_Data
% Load.Span_Load.Load_Diagram_Initial_Data
% 
% Load.Chord_Pressure.Law
% 
% Load.Chord_Pressure.Trapezoid_Xd_Type
% Load.Chord_Pressure.Trapezoid_Xd_Value
% Load.Chord_Pressure.Trapezoid_Xd_Location
% Load.Chord_Pressure.Trapezoid_Xd_Distr_File_Name
% Load.Chord_Pressure.Trapezoid_Xd_Distr_Data
% Load.Chord_Pressure.Trapezoid_Xd_Distr_Initial_Data
% 
% Load.Chord_Pressure.Model_X_p2_p1_Type
% Load.Chord_Pressure.Model_X_p2_p1_Value
% Load.Chord_Pressure.Model_X_p2_p1_Distr_File_Name
% Load.Chord_Pressure.Model_X_p2_p1_Distr_Data
% Load.Chord_Pressure.Model_X_p2_p1_Distr_Initial_Data
% 
% Load.Chord_Pressure.Model_X_p3_p1_Type
% Load.Chord_Pressure.Model_X_p3_p1_Value
% Load.Chord_Pressure.Model_X_p3_p1_Distr_File_Name
% Load.Chord_Pressure.Model_X_p3_p1_Distr_Data
% Load.Chord_Pressure.Model_X_p3_p1_Distr_Initial_Data
% 
% Load.Chord_Pressure.Model_X_p4_p1_Type
% Load.Chord_Pressure.Model_X_p4_p1_Value
% Load.Chord_Pressure.Model_X_p4_p1_Distr_File_Name
% Load.Chord_Pressure.Model_X_p4_p1_Distr_Data
% Load.Chord_Pressure.Model_X_p4_p1_Distr_Initial_Data
% 
% Load.Chord_Pressure.Model_X_f_Type
% Load.Chord_Pressure.Model_X_f_Value
% Load.Chord_Pressure.Model_X_f_Distr_File_Name
% Load.Chord_Pressure.Model_X_f_Distr_Data
% Load.Chord_Pressure.Model_X_f_Distr_Initial_Data
% 
% Load.Chord_Pressure.Model_X_f1_Type
% Load.Chord_Pressure.Model_X_f1_Value
% Load.Chord_Pressure.Model_X_f1_Distr_File_Name
% Load.Chord_Pressure.Model_X_f1_Distr_Data
% Load.Chord_Pressure.Model_X_f1_Distr_Initial_Data
% 
% Load.Chord_Pressure.Model_X_f2_Type
% Load.Chord_Pressure.Model_X_f2_Value
% Load.Chord_Pressure.Model_X_f2_Distr_File_Name
% Load.Chord_Pressure.Model_X_f2_Distr_Data
% Load.Chord_Pressure.Model_X_f2_Distr_Initial_Data
% 
% Load.Chord_Pressure.User_Model_File_Name
% Load.Chord_Pressure.User_Model_Data.Span_Coord
% Load.Chord_Pressure.User_Model_Data.Pressure_Data
% Load.Chord_Pressure.User_Model_Initial_Data.Span_Coord
% Load.Chord_Pressure.User_Model_Initial_Data.Pressure_Data
% 
% Load.Extrapolation.Span_Load_0
% Load.Extrapolation.Span_Load_1
% Load.Extrapolation.Chord_Pressure_0
% Load.Extrapolation.Chord_Pressure_1
% Load.Extrapolation.User_Model_0
% Load.Extrapolation.User_Model_1
% Load.Extrapolation.Trapezoid_Xd_0
% Load.Extrapolation.Trapezoid_Xd_1
% Load.Extrapolation.Model_X_p2_p1_0
% Load.Extrapolation.Model_X_p2_p1_1
% Load.Extrapolation.Model_X_p3_p1_0
% Load.Extrapolation.Model_X_p3_p1_1
% Load.Extrapolation.Model_X_p4_p1_0
% Load.Extrapolation.Model_X_p4_p1_1
% Load.Extrapolation.Model_X_f_0
% Load.Extrapolation.Model_X_f_1
% Load.Extrapolation.Model_X_f1_0
% Load.Extrapolation.Model_X_f1_1
% Load.Extrapolation.Model_X_f2_0
% Load.Extrapolation.Model_X_f2_1
% 
% Load.Summation_Point
% 
% Load.Coord_Origin
% Load.Point_On_Axis_3
% Load.Point_On_Plane_13
% 
% Load.Correction_Coefficient
% 
% Load.Distributed_Load_Mode
% Load.Vector_Field_Component
% Load.Field_Name
% 
% Load.Precomputed_Data.Span_Length
% Load.Precomputed_Data.Root_Chord_Length
% Load.Precomputed_Data.End_Chord_Length
% Load.Precomputed_Data.Span_Pressure_Center
% Load.Precomputed_Data.Linear_Load_Root
% Load.Precomputed_Data.Linear_Load_End
% Load.Precomputed_Data.Linear_Load_Difference
% Load.Precomputed_Data.Chord_Pressure_Center
% Load.Precomputed_Data.Root_Chord_Pressure_Center
% Load.Precomputed_Data.End_Chord_Pressure_Center

% ------------------------------------------------------------------------------------------------------------------------------


% ======== Этап проверки нагружения ========

fprintf (1, 'ПРОВЕРКА НАГРУЖЕНИЯ\n\n');

Load_Summary = Load_Verification(Load);

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

Print_Delimiter();

% ---------------------------------------------- ОПИСАНИЕ СТРУКТУРЫ Load_Summary -----------------------------------------------

% Load_Summary.Summation_Coord
% 
% Load_Summary.Actual_Total_Force_Pn
% Load_Summary.Actual_Total_Force_Pn_Vector
% 
% Load_Summary.Actual_Total_Force_Pt
% Load_Summary.Actual_Total_Force_Pt_Vector
% 
% Load_Summary.Actual_Total_Force
% Load_Summary.Actual_Total_Force_Vector
% 
% Load_Summary.Actual_Total_Moment
% Load_Summary.Actual_Total_Moment_Vector
% 
% Load_Summary.Pressure_Center_XYZ_Projected
% Load_Summary.Pressure_Center_ksi
% Load_Summary.Pressure_Center_etta
% 
% Load_Summary.Actual_Pressure_Center_XYZ
% Load_Summary.Actual_Pressure_Center_XYZ_Projected
% Load_Summary.Actual_Pressure_Center_ksi
% Load_Summary.Actual_Pressure_Center_etta

% ------------------------------------------------------------------------------------------------------------------------------


% ======== Этап записи результатов ========

if (strcmp(Output_File_Format, 'OFF') && strcmp(Write_Current_Config, 'FALSE'))
    
    fprintf (1, 'Запись файла с полем нагрузок была отключена настройкой Output_File_Format = OFF\n');
    fprintf (1, 'Запись конфигурационного файла была отключена настройкой Write_Current_Config = FALSE\n\n');
    
else
    
    fprintf (1, 'ЗАПИСЬ РЕЗУЛЬТАТОВ\n\n');
    
    Date_String = datestr(fix(clock));
    
    switch Output_File_Format
        
        case 'CSV'
            
            Write_CSV(CID_DISTR_LOAD_FIELD, PRESSURE_FIELD, Load, Work_Directory, Date_String);
            
            if (ErrCode < 0)
                fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
                toc;
                return;
            end
            
        case 'SES'
            
            Write_SES(CID_DISTR_LOAD_FIELD, PRESSURE_FIELD, Load, Work_Directory, Date_String);
            
            if (ErrCode < 0)
                fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
                toc;
                return;
            end
            
        case 'BOTH'
            
            Write_CSV(CID_DISTR_LOAD_FIELD, PRESSURE_FIELD, Load, Work_Directory, Date_String);
            
            if (ErrCode < 0)
                fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
                toc;
                return;
            end
            
            Write_SES(CID_DISTR_LOAD_FIELD, PRESSURE_FIELD, Load, Work_Directory, Date_String);
            
            if (ErrCode < 0)
                fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
                toc;
                return;
            end
            
    end
    
    if (strcmp(Write_Current_Config, 'TRUE'))
        
        Write_Config(Work_Directory, Date_String, Load, Input_BDF_name);
        
        if (ErrCode < 0)
            fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
            toc;
            return;
        end
        
    end
    
    Print_Delimiter();
    
end


% ======== Этап визуалиации нагружения ========

if (strcmp(Load_Visualization, 'TRUE'))
    
    if (isempty(ver('MATLAB')))
        
        fprintf (1, 'Графическое окно не было создано, так как визуализация нагружения поддерживается только в среде MATLAB.\n\n');
        
    else
        
        if (strcmp(Need_Reading_BDF_File, 'TRUE') || isempty(Graphic_Window_Handle) || isempty(findall(Graphic_Window_Handle, 'Tag', 'Panel_For_Axes')) || ~strcmp(Previous_Language, Window_Language))
            
            close all;
            
            fprintf (1, 'Создание графического окна...        ');
            
            GW_Set_Graphics_Properties(Window_Language);
            
            GW_Precompute_Graphics(Load, Load_Summary);
            
            GW_Read_Icons();
            
            if (ErrCode < 0)
                fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
                toc;
                return;
            end
            
            GW_Create_Graphic_Window(Load_Summary);
            
        else
            
            fprintf (1, 'Обновление графического окна...      ');
            
            GW_Precompute_Graphics(Load, Load_Summary);
            
            GW_Update_Graphics();
            
        end
        
        fprintf (1, 'OK!\n');
        
    end
    
end

Previous_Language = Window_Language;

% ======== Завершение работы ========

% Сообщение об успешном завершении работы
fprintf (1, '\nРабота программы завершена успешно!\n\n');

% Вывод времени выполнения программы
toc;
